package com.azh;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import com.azh.server.datam.DataManager;
import com.azh.server.server.Server;
import com.azh.server.tables.TableManager;
import com.azh.server.tx.TxManager;
import com.azh.server.util.ExceptionUtils;
import com.azh.server.vm.VersionManager;
import com.azh.server.vm.VersionManagerImpl;

/**
 * @author zhaozhenhang <zhaozhenhang@kuaishou.com>
 * Created on 2022-04-24
 * 启动类
 */
public class Application {

    public static void main(String[] args) throws ParseException {
        Options options = new Options();
        options.addOption("open", true, "-open DBPath");
        options.addOption("create", true, "-create DBPath");
        options.addOption("mem", true, "-mem 64MB");
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options, args);

        if (cmd.hasOption("open")) {
            openDB(cmd.getOptionValue("open"), parseMem(cmd.getOptionValue("mem")));
            return;
        }
        if (cmd.hasOption("create")) {
            createDB(cmd.getOptionValue("create"));
            return;
        }
        System.out.println("Usage: launcher (open|create) DBPath");
    }

    public static final int port = 8999;

    public static final long default_memery = (1 << 20) * 64;

    public static final long KB = 1 << 10;
    public static final long MB = 1 << 20;
    public static final long GB = 1 << 30;

    private static void createDB(String path) {
        TxManager tx = TxManager.create(path);
        DataManager dm = DataManager.create(path, default_memery, tx);
        VersionManager vm = new VersionManagerImpl(tx, dm);
        TableManager.create(path, vm, dm);
        tx.close();
        dm.close();
    }


    private static void openDB(String path, long memery) {
        TxManager tx = TxManager.open(path);
        DataManager dm = DataManager.open(path, memery, tx);
        VersionManager vm = new VersionManagerImpl(tx, dm);
        TableManager tm = TableManager.open(path, vm, dm);
        new Server(port, tm).start();
    }

    private static long parseMem(String memStr) {
        if (memStr == null || "".equals(memStr)) {
            return default_memery;
        }
        if (memStr.length() < 2) {
            ExceptionUtils.getMessage(new RuntimeException("Invalid memory!"));
        }
        String unit = memStr.substring(memStr.length() - 2);
        long memNum = Long.parseLong(memStr.substring(0, memStr.length() - 2));
        switch (unit) {
            case "KB":
                return memNum * KB;
            case "MB":
                return memNum * MB;
            case "GB":
                return memNum * GB;
            default:
                ExceptionUtils.getMessage(new RuntimeException("Invalid memory!"));
        }
        return default_memery;
    }
}
